<template>
  <transition>
    <div
      ref="dragIcon"
      class="dragIcon"
      @touchstart.stop="handleTouchStart"
      @touchmove.prevent.stop="handleTouchMove"
      @touchend.stop="handleTouchEnd"
      @mousedown.stop="handleMouseDown"
      @mouseup.stop="handleMouseUp"
      :style="{ left: left + 'px',top: top + 'px',width: itemWidth + 'px',height: itemHeight + 'px' }"
      v-if="isShow">
      <slot>返回</slot>
    </div>
  </transition>
</template>

<script lang="ts">
import { defineComponent, ref, onMounted, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
export default defineComponent({
  props: {
    itemWidth: {
      type: Number,
      default: 50
    },
    itemHeight: {
      type: Number,
      default: 50
    }
  },
  emits: ['drag-click-event'],
  setup (props) {
    const router = useRouter()
    const left = ref<number>(0)
    const top = ref<number>(0)
    const startToMove = ref<boolean>(false)
    const isShow = ref<boolean>(true)
    const clientW = ref<number>(0)
    const clientH = ref<number>(0)
    const timer = ref<number | null>(null)
    const currentTop = ref<number | null>(null)
    const dragIcon = ref<HTMLElement>()
    const hasMove = ref<boolean>(false)

    const handleScrollStart = () => {
      isShow.value = false
      if (timer.value !== null) {
        clearTimeout(timer.value)
      }
      timer.value = setTimeout(() => {
        handleScrollEnd()
      }, 300)
      currentTop.value = document.documentElement.scrollTop || document.body.scrollTop
    }

    const handleScrollEnd = () => {
      const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
      // 判断是否停止滚动的条件
      if (scrollTop === currentTop.value) {
        isShow.value = true
      }
    }

    const handleIconY = () => {
      if (top.value < 0) {
        // 不上帖上边所以设置为15 没设置0
        top.value = 15
      } else if (top.value + props.itemHeight > clientH.value) {
        // 不让帖下边所以减15
        top.value = clientH.value - props.itemHeight - 15
      }
    }

    const handleTouchStart = () => {
      startToMove.value = true
      hasMove.value = false
      if (dragIcon.value !== undefined) {
        dragIcon.value.style.transition = 'none'
      }
    }

    const handleTouchMove = (e: TouchEvent) => {
      const clientX = e.targetTouches[0].clientX // 手指相对视口的x
      const clientY = e.targetTouches[0].clientY // 手指相对视口的y
      const isInScreen =
        clientX <= clientW.value &&
        clientX >= 0 &&
        clientY <= clientH.value &&
        clientY >= 0
      if (startToMove.value && e.targetTouches.length === 1) {
        if (isInScreen) {
          if (!hasMove.value) {
            hasMove.value = true
          }
          left.value = clientX - props.itemWidth / 2
          top.value = clientY - props.itemHeight / 2
        }
      }
    }

    const handleTouchEnd = () => {
      if (!hasMove.value) {
        dragClick()
        return
      }
      if (left.value < clientW.value / 2) {
        left.value = 15
        // 不让贴边 所以设置15没设置0
        handleIconY()
      } else {
        left.value = clientW.value - props.itemWidth - 15
        // 不让贴边 所以减15
        handleIconY()
      }
      if (dragIcon.value !== undefined) {
        dragIcon.value.style.transition = 'all .3s'
      }
    }

    const handleMouseMove = (e: MouseEvent) => {
      if (!startToMove.value || e.type !== 'mousemove') {
        return
      }
      const clientX = e.clientX // 手指相对视口的x
      const clientY = e.clientY // 手指相对视口的y
      const isInScreen =
        clientX <= clientW.value &&
        clientX >= 0 &&
        clientY <= clientH.value &&
        clientY >= 0
      if (isInScreen) {
        if (!hasMove.value) {
          hasMove.value = true
        }
        left.value = clientX - props.itemWidth / 2
        top.value = clientY - props.itemHeight / 2
      }
    }

    const handleMouseDown = () => {
      startToMove.value = true
      hasMove.value = false
      document.addEventListener('mousemove', handleMouseMove)
      if (dragIcon.value !== undefined) {
        dragIcon.value.style.transition = 'none'
      }
    }

    const handleMouseUp = () => {
      startToMove.value = false
      document.removeEventListener('mousemove', handleMouseMove)
      if (!hasMove.value) {
        dragClick()
        return
      }
      if (left.value < clientW.value / 2) {
        left.value = 15
        handleIconY()
      } else {
        left.value = clientW.value - props.itemWidth - 15
        handleIconY()
      }
      if (dragIcon.value !== undefined) {
        dragIcon.value.style.transition = 'all .3s'
      }
    }

    onMounted(() => {
      clientH.value = document.documentElement.clientHeight
      clientW.value = document.documentElement.clientWidth
      left.value = clientW.value - props.itemWidth - 15
      top.value = clientH.value / 2 - props.itemHeight / 2

      window.addEventListener('scroll', handleScrollStart)
    })

    const dragClick = () => {
      router.back()
      // context.emit('drag-click-event')
    }

    onUnmounted(() => {
      window.removeEventListener('scroll', handleScrollStart)
    })
    return {
      left,
      top,
      startToMove,
      isShow,
      clientW,
      clientH,
      dragIcon,
      handleTouchStart,
      handleTouchMove,
      handleTouchEnd,
      handleMouseMove,
      handleMouseDown,
      handleMouseUp
    }
  }
})
</script>

<style scoped>
.dragIcon {
  z-index: 999;
  user-select: none;
  cursor: move;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  position: fixed;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  /* 浏览器不支持的时候显示 */
  background-color: #2270fe;
  background-image: linear-gradient(45deg, #2270fe, #1c96f9);
  color: #fff;
  box-shadow: 0 0 10px #2270fe;
  word-wrap: break-word;
  word-break: break-all;
}
</style>
